package com.mashibing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mashibing.internalcommon.constant.CommonStatusEnum;
import com.mashibing.internalcommon.dto.PriceRule;
import com.mashibing.internalcommon.dto.ResponseResult;
import com.mashibing.internalcommon.request.ForecastPriceDTO;
import com.mashibing.internalcommon.response.DirectionResponse;
import com.mashibing.internalcommon.response.ForecastPriceResponse;
import com.mashibing.internalcommon.util.BigDecimalUtils;
import com.mashibing.mapper.ServicePriceMapper;
import com.mashibing.remote.ServiceMapClient;
import com.mashibing.service.ForecastPriceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class ForecastPriceServiceImpl implements ForecastPriceService {

    @Autowired
    private ServiceMapClient serviceMapClient;

    @Autowired
    private ServicePriceMapper servicePriceMapper;

    @Override
    public ResponseResult forecastPrice(ForecastPriceDTO forecastPriceDTO) {

        String depLongitude = forecastPriceDTO.getDepLongitude();
        String depLatitude = forecastPriceDTO.getDepLatitude();
        String destLongitude = forecastPriceDTO.getDestLongitude();
        String destLatitude = forecastPriceDTO.getDestLatitude();

        // 调用map服务
        log.info("出发地经度：" + depLongitude);
        log.info("出发地纬度：" + depLatitude);
        log.info("目的地经度：" + destLongitude);
        log.info("目的地纬度：" + destLatitude);

        log.info("调用地图服务，查询距离和时长");
        ResponseResult<DirectionResponse> direction = serviceMapClient.direction(forecastPriceDTO);

        // 处理结果，获取距离和时长
        Integer distance = direction.getData().getDistance();
        Integer duration = direction.getData().getDuration();
        log.info("对应两地距离为：" + distance);
        log.info("对应两地所需时间为：" + duration);

        // 获取计价规则
        QueryWrapper<PriceRule> wrapper = new QueryWrapper<>();
        wrapper.eq("city_code",forecastPriceDTO.getCityCode());
        wrapper.eq("vehicle_type",forecastPriceDTO.getVehicleType());
        wrapper.orderByDesc("fare_version");

        List<PriceRule> priceRules = servicePriceMapper.selectList(wrapper);
        if (priceRules.isEmpty()) {
            throw new IllegalArgumentException("参数错误，没有对应的计价规则");
        }
        PriceRule priceRule = priceRules.get(0);

        // 计算预估价格
        double price = getPrice(distance, duration, priceRule);

        ForecastPriceResponse forecastPriceResponse = new ForecastPriceResponse();
        forecastPriceResponse.setPrice(price);
        forecastPriceResponse.setCityCode(priceRule.getCityCode());
        forecastPriceResponse.setVehicleType(priceRule.getVehicleType());
        forecastPriceResponse.setFareType(priceRule.getFareType());
        forecastPriceResponse.setFareVersion(priceRule.getFareVersion());

        return ResponseResult.success(forecastPriceResponse);
    }

    @Override
    public ResponseResult<Double> calculatePrice(Integer distance, Integer duration, String cityCode, String vehicleType) {
        // 查询计价规则
        QueryWrapper<PriceRule> priceRulequeryWrapper = new QueryWrapper<>();
        priceRulequeryWrapper.eq("city_code",cityCode);
        priceRulequeryWrapper.eq("vehicle_type",vehicleType);
        priceRulequeryWrapper.orderByDesc("fare_version");

        List<PriceRule> priceRules = servicePriceMapper.selectList(priceRulequeryWrapper);
        if (priceRules.isEmpty()){
            return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_EMPTY.getCode(),CommonStatusEnum.VERIFICATION_CODE_ERROR.getMessage());
        }

        // 计算
        double price = getPrice(distance, duration, priceRules.get(0));
        return ResponseResult.success(price);
    }

    /**
     * 根据距离，时间，计价规则计算预估价格
     *
     * @param distance
     * @param duration
     * @param priceRule
     * @return
     */
    private static double getPrice(Integer distance, Integer duration, PriceRule priceRule) {
        double price = 0;

        // 起步价
        Double startFare = priceRule.getStartFare();
        price = BigDecimalUtils.add(startFare, price);

        // 里程数价
        Integer startMile = priceRule.getStartMile();
        double subDistance = BigDecimalUtils.substract(BigDecimalUtils.divide(distance, 1000), startMile);
        if (subDistance > 0) {
            double multiplyPrice = BigDecimalUtils.multiply(subDistance, priceRule.getUnitPricePerMile());
            price += multiplyPrice;
        }

        // 时长费
        double multiplyMinute = BigDecimalUtils.multiply(BigDecimalUtils.divide(duration, 60), priceRule.getUnitPricePerMinute());
        price += multiplyMinute;
        price = BigDecimal.valueOf(price).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

        return price;
    }

    public static void main(String[] args) {
        PriceRule priceRule = new PriceRule();
        priceRule.setUnitPricePerMile(1.8);
        priceRule.setUnitPricePerMinute(0.5);
        priceRule.setStartFare(10.0);
        priceRule.setStartMile(3);

        System.out.println(getPrice(38253, 2967, priceRule));
    }


}
